﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Mvc;
using TjZheng.Framework;

namespace TjZheng.Controls
{
    /// <summary>
    /// 查询条件组织（不组织参数化查询）
    /// </summary>
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
    public class QueryFilter : FilterAttribute, IActionFilter
    {
        /// <summary>
        /// 字段条件组织，如Name组织 Name=Request[Name]
        /// </summary>
        protected string Param { get; set; }
        /// <summary>
        /// 字段条件批量组织，如Name,Code组织 Name=Request[Name] AND Code=Request[Code]
        /// </summary>
        protected List<string> Params { get; set; }
        /// <summary>
        /// 手动组织条件，如Name=具体值
        /// </summary>
        public string OtherConditions { get; set; }
        /// <summary>
        /// 构造函数
        /// </summary>
        public QueryFilter()
        {
        }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="Param">字段条件组织，如Name组织 Name=Request[Name]</param>
        public QueryFilter(string Param)
            : this(Param, string.Empty)
        {
        }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="Params">字段条件批量组织，如Name,Code组织 Name=Request[Name] AND Code=Request[Code]</param>
        public QueryFilter(List<string> Params)
            : this(Params, string.Empty)
        {
        }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="Param">字段条件组织，如Name组织 Name=Request[Name]</param>
        /// <param name="OtherConditions">手动组织条件，如Name=具体值</param>
        public QueryFilter(string Param, string OtherConditions)
        {
            this.Param = Param;
            this.OtherConditions = OtherConditions;
        }
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="Params">字段条件组织，如Name组织 Name=Request[Name]</param>
        /// <param name="OtherConditions">手动组织条件，如Name=具体值</param>
        public QueryFilter(List<string> Params, string OtherConditions)
        {
            this.Params = Params;
            this.OtherConditions = OtherConditions;
        }

        public virtual void OnActionExecuted(ActionExecutedContext filterContext)
        {

        }

        public virtual void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (filterContext == null)
            {
                throw new ArgumentNullException("filterContext");
            }
            var objValueProvider = filterContext.Controller.ValueProvider;
            var objController = filterContext.Controller as Controller;
            List<string> QueryConditionList = new List<string>();
            if (Param.IsNoNull())
            {
                string objParamValue = filterContext.HttpContext.Request[Param].FilterSql();
                if (objParamValue.IsNoNull())
                {
                    QueryConditionList.Add(string.Format("{0}={1}", Param, objParamValue));
                }
            }
            if (Params.IsNoNull())
            {
                foreach (var objParam in Params)
                {
                    string objParamValue = filterContext.HttpContext.Request[objParam].FilterSql();
                    if (objParamValue.IsNoNull())
                    {
                        QueryConditionList.Add(string.Format("{0}={1}", objParam, objParamValue));
                    }
                }
            }
            if (OtherConditions.IsNoNull())
            {
                QueryConditionList.Add(OtherConditions);
            }
            string QueryCondition = string.Empty;
            if (!objValueProvider.ContainsPrefix("QueryInfo.Prefixs"))
            {
                if (QueryConditionList.IsNoNull())
                {
                    QueryCondition = QueryConditionList.Aggregate((x, y) => x + " AND " + y);
                    //filterContext.Controller.ViewBag.QueryCondition = QueryCondition;

                    filterContext.Controller.ViewBag.QueryResult = new QueryResult
                    {
                        Condition = QueryCondition
                    };
                }
                return;
            }
            var objValueProviderResult = objValueProvider.GetValue("QueryInfo.Prefixs");
            if (objValueProviderResult == null)
            {
                objValueProviderResult = objValueProvider.GetValue("QueryInfo.Prefixs[]");
                if (objValueProviderResult == null)
                {
                    if (QueryConditionList.IsNoNull())
                    {
                        QueryCondition = QueryConditionList.Aggregate((x, y) => x + " AND " + y);
                        //filterContext.Controller.ViewBag.QueryCondition = QueryCondition;

                        filterContext.Controller.ViewBag.QueryResult = new QueryResult
                        {
                            Condition = QueryCondition
                        };
                    }
                    return;
                }
            }
            List<QueryInfo> QueryInfoList = new List<QueryInfo>();
            foreach (var prefix in objValueProviderResult.RawValue as string[])
            {
                if (objValueProvider.ContainsPrefix(prefix))
                {
                    QueryInfo objQueryInfo = new QueryInfo() { Prefix = prefix };
                    //Predicate<string> propertyFilter = propertyName => BindAttribute.IsPropertyAllowed(propertyName, null, null);
                    IModelBinder objModelBinder = ModelBinders.Binders.GetBinder(typeof(QueryInfo));
                    ModelBindingContext objModelBindingContext = new ModelBindingContext()
                    {
                        ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => objQueryInfo, typeof(QueryInfo)),
                        ModelName = prefix,
                        ModelState = objController.ModelState,
                        //PropertyFilter = propertyFilter,
                        ValueProvider = objValueProvider
                    };
                    objModelBinder.BindModel(objController.ControllerContext, objModelBindingContext);
                    if (objController.ModelState.IsValid)
                    {
                        objQueryInfo.QueryValue = objQueryInfo.QueryValue.FilterSql();
                        QueryInfoList.Add(objQueryInfo);
                        string condition = objQueryInfo.GetCondition();
                        if (condition.IsNoNull())
                        {
                            QueryConditionList.Add(condition);
                        }
                    }
                }
            }
            if (QueryConditionList.IsNoNull())
            {
                QueryCondition = QueryConditionList.Aggregate((x, y) => x + " AND " + y);
            }

            //filterContext.Controller.ViewBag.QueryCondition = QueryCondition;
            //filterContext.Controller.ViewBag.QueryInfos = QueryInfoList;

            filterContext.Controller.ViewBag.QueryResult = new QueryResult
            {
                Condition = QueryCondition,
                QueryInfos = QueryInfoList
            };
        }
    }
}